package com.bzyd.verify.imagecode;

import com.bzyd.verify.utils.CookieUtil;
import com.bzyd.verify.utils.RedisUtil;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;

/**
 * 图片验证码处理器
 */
public class ImageCodeGenerator {


    private Random random;
    private ImageCodeProperties imageCodeProperties;

    public ImageCodeGenerator(ImageCodeProperties imageCodeProperties) {
        this.imageCodeProperties = imageCodeProperties;
        this.random = new Random();
    }

    /**
     * 生成图片验证码
     *
     * @param response
     */
    public String getRandomCode(HttpServletResponse response) throws IOException {
        // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
        BufferedImage image = new BufferedImage(imageCodeProperties.getWidth(), imageCodeProperties.getHeight(), BufferedImage.TYPE_INT_BGR);
        // 产生Image对象的Graphics对象,该对象可以在图像上进行各种绘制操作
        Graphics g = image.getGraphics();
        g.fillRect(0, 0, imageCodeProperties.getWidth(), imageCodeProperties.getHeight());//图片大小
        g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//字体大小
        g.setColor(getRandColor(110, 133));//字体颜色
        //绘制干扰线
        for (int i = 0; i < imageCodeProperties.getLineNum(); i++) {
            drawLine(g);
        }

        //绘制随机字符
        String s = "";
        for (int i = 0; i < imageCodeProperties.getCharNum(); i++) {
            s = drawString(g, s, i);
        }

        g.dispose();

        //存储到redis
        String key = UUID.randomUUID().toString();
        RedisUtil.set(key,s,imageCodeProperties.getCacheTime());

        //提供两种方式把key返回给前端
        //方式一：cookie
        CookieUtil.addCookie(response,"verid",key,-1);

        //方式二：在响应报文头中设置
        response.setHeader("verid",key);

        //输出图片到客户端
        response.setContentType("image/jpeg");
        ImageIO.write(image, "JPEG", response.getOutputStream());
        return s;
    }

    /**
     * 绘制字符串
     *
     * @param g
     * @param s
     * @param i
     * @return
     */
    private String drawString(Graphics g, String s, int i) {
        g.setFont(getFont());
        g.setColor(new Color(random.nextInt(101), random.nextInt(111), random.nextInt(121)));
        String rand = getRandomString(random.nextInt(imageCodeProperties.getRange().length()));
        s += rand;
        g.drawString(rand, 13 * i, 16);
        return s;
    }

    private String getRandomString(int index) {
        return String.valueOf(imageCodeProperties.getRange().charAt(index));
    }

    /**
     * 获得字体
     *
     * @return
     */
    private Font getFont() {
        return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
    }

    /**
     * 绘制干扰线
     *
     * @param g
     */
    private void drawLine(Graphics g) {
        int x = random.nextInt(imageCodeProperties.getWidth());
        int y = random.nextInt(imageCodeProperties.getHeight());
        int x1 = random.nextInt(13);
        int y1 = random.nextInt(15);
        g.drawLine(x, y, x + x1, y + y1);
    }

    /**
     * 获得随机颜色
     *
     * @param fc
     * @param bc
     * @return
     */
    private Color getRandColor(int fc, int bc) {
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc - fc - 16);
        int g = fc + random.nextInt(bc - fc - 14);
        int b = fc + random.nextInt(bc - fc - 18);
        return new Color(r, g, b);
    }

}
